package com.chen.ppos;

import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.security.GeneralSecurityException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.chen.posp.sodexo.mac.DesUtils;
import com.chen.posp.sodexo.util.EncodeUtil;


public class Test {
	private Log log = LogFactory.getLog(Test.class);
	/**
	 * 
	* @描述: 报文解析
	* @创建人:cyb
	* @创建时间:2018年3月26日 上午11:42:11
	* @修改人：
	* @修改时间：
	* @修改描述
	* @param @param requestBytes
	* @param @return
	* @return UnionPayParam
	* @throws
	 */
	public UnionPayParam Decoding(byte[] requestBytes){
		log.info("requestBytes=" + ISO8583Utile.bytesToHexString(requestBytes));
		byte[] requestByte = new byte[requestBytes.length - 2]; // 去掉两位(00+报文长度)
		int contenlen = requestBytes.length - 2;
		System.out.println("contenlen=" + contenlen);
		System.arraycopy(requestBytes, 2, requestByte, 0, contenlen);
		int offset = 0;

		UnionPayParam unionPayParam = new UnionPayParam();

		// 检查TPUD
		if (contenlen < Constant.LEN_POS_TPUD) {
			log.info("POSISO8583 Decoding parse message fail, data len less than TPUD's length");
			return null;
		}

		byte[] tpudtype = new byte[Constant.LEN_POS_TPUD];
		System.arraycopy(requestByte, offset, tpudtype, 0, Constant.LEN_POS_TPUD);
		String tpdu = ISO8583Utile.bcd2String(tpudtype, false);
		log.info("tpdu=" + tpdu);
		unionPayParam.setTPDU(tpdu);

		contenlen -= Constant.LEN_POS_TPUD;
		offset += Constant.LEN_POS_TPUD;

		byte[] lri = new byte[Constant.LEN_POS_LRI]; // 拨号POS标识
//		System.arraycopy(requestByte, offset, lri, 0, Constant.LEN_POS_LRI);

		byte[] l2 = new byte[2];
		//System.arraycopy(requestByte, offset + 2, l2, 0, 2);

		//String lriTemp = new String(lri);
//		log.info("the POS message head  lriTemp [" + lriTemp + "] ");
//		boolean lriFlag = false;
//		if (Constant.CONTENT_POS_LRI.equals(lriTemp)) {
//			lriFlag = true;
//			log.info("go into pos_lri success! contenlen[" + contenlen + "]");
//			int byteStart = offset;
//			byte[] lrilength = new byte[2];
//			System.arraycopy(requestByte, byteStart + 3, lrilength, 0, 2); // 长度
//			byteStart += Constant.LEN_POS_LRI;
//			byteStart += 2;  // 略过2字节的长度域
//			byte[] sourcePhonebyte = new byte[Constant.LEN_POS_PHONE];
//			System.arraycopy(requestByte, byteStart, sourcePhonebyte, 0, Constant.LEN_POS_PHONE);
//			byteStart += Constant.LEN_POS_PHONE;
//			byte[] destPhonebyte = new byte[Constant.LEN_POS_PHONE];
//			System.arraycopy(requestByte, byteStart, destPhonebyte, 0, Constant.LEN_POS_PHONE);
//			byteStart += Constant.LEN_POS_PHONE;
//			byteStart += 4;  // 略过4个字节的分隔符和长度域
//			byte[] nodebyte = new byte[Constant.LEN_POS_NODE];
//			System.arraycopy(requestByte, byteStart, nodebyte, 0, Constant.LEN_POS_NODE);
//			byteStart += Constant.LEN_POS_NODE;
//			offset += 33;  // 略过33个字节的拨号POS特殊报文域
//			contenlen -= 33;
//			// 处理来电电话和被叫电话
//			String callPhoneNo = ISO8583Utile.bcd2String(sourcePhonebyte, false);
//			String servicePhoneNo = ISO8583Utile.bcd2String(destPhonebyte, false);
//			unionPayParam.setCallPhoneNo(callPhoneNo);
//			unionPayParam.setServicePhoneNo(servicePhoneNo);
//
//		}

		// 检查报文头
		if (contenlen < Constant.LEN_POS_Message) {
			log.info("POSISO8583 Decoding parse message fail, data len less than CERTIFIED VERSION's length");
			return null;
		}
		//byte[] versiontype = new byte[Constant.LEN_POS_Message];
		//System.arraycopy(requestByte, offset, versiontype, 0, Constant.LEN_POS_Message);
		//String version = ISO8583Utile.bcd2String(versiontype, false);
		//log.info("version=" + version);
		//PosManufacturer posManufacturer = (PosManufacturer) Constant.contentMessageMap.get(version); // 报文上送厂商

		
//		contenlen -= Constant.LEN_POS_Message;
//		offset += Constant.LEN_POS_Message;

		byte[] decodeingByte = new byte[contenlen];
		log.info("requestByte=" + ISO8583Utile.bytesToHexString(requestByte) + "," + requestByte.length);
		System.arraycopy(requestByte, offset, decodeingByte, 0, contenlen);
		log.info("decodeingByte=" + ISO8583Utile.bytesToHexString(decodeingByte)+ "," + decodeingByte.length);
		
		Posiso8583 posiso8583 = new CommonPosiso8583(); // 默认

		try {
			System.out.println("decodeingByte=" + decodeingByte.length + ",contenlen=" + contenlen);
			unionPayParam = (UnionPayParam) posiso8583.Decoding(decodeingByte, contenlen, unionPayParam);
		} catch (Exception e) {
		} 
		//校验mac
		String macString = unionPayParam.getMac();
		return unionPayParam;
	}
	
	
	public static void main(String[] args) throws Exception {
		Test t = new Test();
		//t.mkk();
		//主密钥密文:1C74CE5C23031CB261C26516
//		String zhmiyuemingwen = "";
//		try {
//			String key = "4462002EC6FD9BB94462002EC6FD9BB9";
//			byte[] r = DesUtils.decryptBy3DesEcb("1C74CE5C23031CB2".getBytes(), key.getBytes());
//			//得到主密钥明文
//			zhmiyuemingwen = ISO8583Utile.bytesToHexString(r);
//			System.out.println("zhmiyuemingwen=" +zhmiyuemingwen);
//		} catch (GeneralSecurityException e) {
//			e.printStackTrace();
//		}
//////		
////		//签到得到mackey密文
////		//t.sign();
////		//DFD515FC6FF5A15AA5C950C6
//		//用主密钥明文解密mackey
//		String macKey = "";
//		try {
//			byte[] r = DesUtils.decryptBy3DesEcb("DFD515FC6FF5A15A".getBytes(), zhmiyuemingwen.getBytes());
//			//得到macKey明文
//			macKey = ISO8583Utile.bytesToHexString(r);
//		} catch (GeneralSecurityException e) {
//			e.printStackTrace();
//		}
//		System.out.println("macKey=" + macKey);
//		
		
		
//		//demo的扫码支付返回91
//		//用demo例子来算mac
		//取得demo的主密钥明文
		//String mkk = "006a600000001108102020010002e000049913800000400012303030303030303030313030303030303030303030303030324348494e4120504f53205445524d494e414c205445535430303030343000000000000000000000000016952907152758ed4b1e7941615db9ac6d";
		//t.Decoding(ISO8583Utile.string2Bcd(mkk));
		//主密钥密文
		String TMK = "952907152758ED4B1E7941615DB9AC6D";
		
		String zhmiyuemingwen = "";
		byte[] r = null;
		try {
			String key = "99BFDDF31B204664F099BFDDF31B204664F0";
			r = DesUtils.decryptBy3DesEcb("952907152758ed4b".getBytes(), key.getBytes());
			r = DesUtils.decryptBy3DesCbc("952907152758ed4b".getBytes(), key.getBytes());
			//得到主密钥明文
			zhmiyuemingwen = EncodeUtil.hex(r);
		} catch (GeneralSecurityException e) {
			e.printStackTrace();
		}
		
		System.out.println("zhmiyuemingwen=" + zhmiyuemingwen);
		
		//获取macKey密文
		//String macKey = "006860000000110810a038010002a00004000000000000000099048000004207510805140012303030303030303030314348494e4120504f53205445524d494e414c205445535430303030343200000000000000000000000016f9f378fd517c9ecac231193c04d4f143";
		//t.Decoding(ISO8583Utile.string2Bcd(macKey));
		String macKey = "F9F378FD517C9ECAC231193C04D4F143";
		//用主密钥明文解密mackey 
		byte[] rr = DesUtils.decryptBy3DesCbc("F9F378FD517C9ECA".getBytes(), r);
		String macKeySrc = EncodeUtil.hex(rr);
		System.out.println(macKeySrc);
		
		
//		
////		s = "006a600000001108102020010002e000049913800000400012303030303030303030313030303030303030303030303030324348494e4120504f53205445524d494e414c205445535430303030343000000000000000000000000016952907152758ed4b1e7941615db9ac6d";
////		UnionPayParam param = t.Decoding(ISO8583Utile.string2Bcd(s));
//		String key = "4462002EC6FD9BB94462002EC6FD9BB9";
//		try {
//			String b = "7B5DBF73DA98CA7663B99B70";
//			byte[] r = DesUtils.decryptBy3DesEcb(b.getBytes(), key.getBytes());
//			//System.out.println("result=" + ISO8583Utile.hex(r));
//			
//		} catch (GeneralSecurityException e) {
//			e.printStackTrace();
//		}
//		//主密钥明文：DCEF39996565CDB190467487ABCDEA132C7A363B0FF98B00
//		//MACKEY：95F910E8F978E58F4E7F11E6
//		
//		byte[] r = DesUtils.decryptBy3DesEcb("95F910E8F978E58F4E7F11E6".getBytes(), "DCEF39996565CDB190467487ABCDEA132C7A363B0FF98B00".getBytes());
//		//System.out.println("result=" + ISO8583Utile.hex(r));
		
		//mackey明文:618D3255E72EE9B4132F696DC6A8ABFBC99380AF3ABD4A84
		
		//domo 扫码
		//String s = "0065600087000001007038448000C1800116111111123456789000000000000000000100000513585101303730313109000030303031323733373030303030303030303030303530300018373731303635393337373639343732313339015661585890413A714B";
		//s = "007960000000870110703844800EC180011611111112345678900000000000000000010000051359060130373031310900003830333030343030303030353334323333323030303030313237333730303030303030303030303035303000183737313036353933373736393437323133390156D0E4ACF31F713A6A";
		//     007960000000870110703844800EC1800116111111123456789000000000000000000100000515122703273730313109000038303836323730303030303530303030303039313030303132373337303030303030303030303030353030001837373130363539333737363934373231333901566800000000000000
		//s = "0056600011000005002020010000c000129600000000550012303030303030303130303030303030303030303030303200063030303037320030303031303030303030303030303636303030303030303030303030303030";
		//t.Decoding(ISO8583Utile.hexStringToByte(s));
		//t.purchase("");
		//t.sign();

//		
	}
	
	public void mkk(){
		String tid="00002395";
		String mid="000000000000057";
		
		Posiso8583 commonPosiso8583 = new CommonPosiso8583();
		commonPosiso8583.putField(0, "0800");
		commonPosiso8583.putField(3, "991380");
		commonPosiso8583.putField(11, "000040");
		commonPosiso8583.putField(24, "001");
		commonPosiso8583.putField(41, tid);
		commonPosiso8583.putField(42, mid);
		commonPosiso8583.putField(43, "CHINA POS TERMINAL TEST000042");
		commonPosiso8583.putField(62, "000042");
		
		
		byte[] sendData = commonPosiso8583.Encoding();
		String ip="58.215.166.38";
		int port=1005;
		
		Socket socket = new Socket();
		InetAddress inetAddress;
		try {
			inetAddress = InetAddress.getByName(ip);
			
			InetSocketAddress address = new InetSocketAddress(inetAddress, port);
			
			InputStream io = null;
			OutputStream out = null;
			
			socket.setReuseAddress(true);
			socket.connect(address);
			socket.setSoTimeout(18000);
			//发送数据
			socket.getOutputStream().write(sendData);
			socket.getOutputStream().flush();
			
			
			io = socket.getInputStream();
			byte[] posInput = new byte[1024];
			int realLength = io.read(posInput);
			byte[] realInput = new byte[realLength];
			System.arraycopy(posInput, 0, realInput, 0, realLength);
			Decoding(realInput);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public void purchase(String macKeySrc){
		String tid="00002395";
		tid = "00012737";
		String mid="000000000000057";
		mid = "000000000000500";
		
		Posiso8583 commonPosiso8583 = new CommonPosiso8583();
		commonPosiso8583.putField(0, "0100");
		commonPosiso8583.putField(2, "1111111234567890");
		commonPosiso8583.putField(3, "000000");
		commonPosiso8583.putField(4, "000000000001");
		commonPosiso8583.putField(11, "000005");
		commonPosiso8583.putField(12, "135851");//HHMMSS
		commonPosiso8583.putField(13, "0130");// MMDD
		commonPosiso8583.putField(18, "7011");
		commonPosiso8583.putField(22, "900");
		commonPosiso8583.putField(25, "00");
		//commonPosiso8583.putField(35, "00123213");
		commonPosiso8583.putField(41, tid);
		commonPosiso8583.putField(42, mid);
		commonPosiso8583.putField(48, "771065937769472139");
		commonPosiso8583.putField(49, "156");
		//commonPosiso8583.putField(64, "000041");
		
		//String s = "0065600087000001007038448000C1800116111111123456789000000000000000000100000513585101303730313109000030303031323733373030303030303030303030303530300018373731303635393337373639343732313339015661585890413A714B";
		byte[] sendData = commonPosiso8583.Encoding();
		//byte[] sendData = ISO8583Utile.hexStringToByte(s);
		String ip="58.215.166.38";
		int port=1005;
		
		Socket socket = new Socket();
		InetAddress inetAddress;
		try {
			inetAddress = InetAddress.getByName(ip);
			
			InetSocketAddress address = new InetSocketAddress(inetAddress, port);
			
			InputStream io = null;
			OutputStream out = null;
			
			socket.setReuseAddress(true);
			socket.connect(address);
			socket.setSoTimeout(18000);
			//发送数据
			socket.getOutputStream().write(sendData);
			socket.getOutputStream().flush();
			
			
			io = socket.getInputStream();
			byte[] posInput = new byte[1024];
			int realLength = io.read(posInput);
			byte[] realInput = new byte[realLength];
			System.arraycopy(posInput, 0, realInput, 0, realLength);
			//System.out.println(ISO8583Utile.bcd2String(realInput, false));
			//System.out.println("abc::"+ISO8583Utile.hex(realInput));
			Decoding(realInput);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	
	public void sign(){
		String tid="00002395";
		String mid="000000000000057";
		
		Posiso8583 commonPosiso8583 = new CommonPosiso8583();
		commonPosiso8583.putField(0, "0800");
		commonPosiso8583.putField(3, "990480");
		commonPosiso8583.putField(11, "000040");
		commonPosiso8583.putField(24, "012");
		commonPosiso8583.putField(41, tid);
		commonPosiso8583.putField(42, mid);
		commonPosiso8583.putField(43, "CHINA POS TERMINAL TEST000042");
		commonPosiso8583.putField(62, "000042");
		
		
		byte[] sendData = commonPosiso8583.Encoding();
		String ip="58.215.166.38";
		int port=1005;
		
		Socket socket = new Socket();
		InetAddress inetAddress;
		try {
			inetAddress = InetAddress.getByName(ip);
			
			InetSocketAddress address = new InetSocketAddress(inetAddress, port);
			
			InputStream io = null;
			OutputStream out = null;
			
			socket.setReuseAddress(true);
			socket.connect(address,1800000);
			//socket.setSoTimeout(18000);
			//发送数据
			socket.getOutputStream().write(sendData);
			socket.getOutputStream().flush();
			
			
			io = socket.getInputStream();
			byte[] posInput = new byte[1024];
			int realLength = io.read(posInput);
			byte[] realInput = new byte[realLength];
			System.arraycopy(posInput, 0, realInput, 0, realLength);
			System.out.println(ISO8583Utile.bcd2String(realInput, false));
			Decoding(realInput);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}


}
